package com.ikingtech.framework.sdk.pay.embedded.supplier.allinpay;

import com.ikingtech.framework.sdk.utils.Tools;
import lombok.Data;

import java.io.Serial;
import java.io.Serializable;
import java.util.Map;

/**
 * 通联支付-收银宝-网上收银统一支付接口参数
 *
 * @author tie yan
 */
@Data
public class AllInPaySybPayParam implements Serializable {

    @Serial
    private static final long serialVersionUID = 5802575916769328057L;

    protected AllInPaySybPayParam(Builder builder) {
        this.cusid = builder.cusid;
        this.appid = builder.appid;
        this.version = builder.version;
        this.trxamt = builder.trxamt;
        this.reqsn = builder.reqsn;
        this.paytype = builder.paytype;
        this.randomstr = builder.randomstr;
        this.body = builder.body;
        this.remark = builder.remark;
        this.validtime = builder.validtime;
        this.acct = builder.acct;
        this.notify_url = builder.notify_url;
        this.limit_pay = builder.limit_pay;
        this.sub_appid = builder.sub_appid;
        this.goods_tag = builder.goods_tag;
        this.benefitdetail = builder.benefitdetail;
        this.chnlstoreid = builder.chnlstoreid;
        this.subbranch = builder.subbranch;
        this.extendparams = builder.extendparams;
        this.cusip = builder.cusip;
        this.front_url = builder.front_url;
        this.idno = builder.idno;
        this.truename = builder.truename;
        this.asinfo = builder.asinfo;
        this.fqnum = builder.fqnum;
        this.signtype = builder.signtype;
        this.unpid = builder.unpid;
        this.sign = builder.sign;
        this.terminfo = builder.terminfo;
        this.operatorid = builder.operatorid;
        this.oldreqsn = builder.oldreqsn;
        this.trxid = builder.trxid;
        this.oldtrxid = builder.oldtrxid;
    }

    public String toQueryStr(String privateKey) {
        Map<Object, Object> paramMap = Tools.Bean.convertToMap(this);
        this.setSign(Tools.Encrypt.rsa(Tools.Http.toQueryStr(paramMap), privateKey));
        return Tools.Http.toQueryStr(paramMap, true);
    }

    public static Builder builder() {
        return new Builder();
    }

    /**
     * 商户号
     * 实际交易的商户号
     */
    private String cusid;

    /**
     * 应用ID
     * 平台分配的APPID
     */
    private String appid;

    /**
     * 接口版本号
     * 默认填11
     */
    private String version;

    /**
     * 交易金额
     * 单位为分
     */
    private String trxamt;

    /**
     * 商户交易单号
     * 商户的交易订单号，保证商户平台唯一
     */
    private String reqsn;

    /**
     * 交易方式
     * W01 -- 微信扫码支付
     * W02 -- 微信JS支付
     * W06 -- 微信小程序支付
     * A01 -- 支付宝扫码支付
     * A02 -- 支付宝JS支付
     * A03 -- 支付宝APP支付
     * Q01 -- 手机QQ扫码支付
     * Q02 -- 手机QQ JS支付
     * U01 -- 银联扫码支付(CSB)
     * U02 -- 银联JS支付
     * S03 -- 数字货币H5
     */
    private String paytype;

    /**
     * 随机字符串
     * 商户自行生成的随机字符串
     */
    private String randomstr;

    /**
     * 订单标题
     * 订单商品名称，为空则以商户名作为商品名称
     * 最大100个字节(注：utf8下，一个中文字符是3个字节)
     */
    private String body;

    /**
     * 备注信息
     * 最大160个字节(80个中文字符)
     */
    private String remark;

    /**
     * 有效时间
     * 订单有效时间，以分为单位，不填默认为5分钟
     * 最大1440分钟
     */
    private String validtime;

    /**
     * 支付平台用户标识
     * JS支付时使用
     * 微信支付-用户的微信openid
     * 付宝支付-用户user_id
     * 微信小程序-用户小程序的openid
     */
    private String acct;

    /**
     * 交易结果通知地址
     * 接收交易结果的通知回调地址，通知url必须为直接可访问的url，不能携带参数。
     * 若使用https,需使用默认443端口
     */
    private String notify_url;

    /**
     * 支付限制
     * no_credit--指定不能使用信用卡支付
     * 暂时只对微信支付和支付宝有效,仅支持no_credit
     */
    private String limit_pay;

    /**
     * 微信子appid
     * 微信小程序/微信公众号/APP的appid
     * 只对微信支付有效
     */
    private String sub_appid;

    /**
     * 订单优惠标识
     * 订单优惠标记，用于区分订单是否可以享受优惠，字段内容在微信后台配置券时进行设置，说明详见代金券或立减优惠
     * 只对微信支付有效
     * 微信扫码支付 交易方式不支持
     */
    private String goods_tag;

    /**
     * 优惠信息
     * Benefitdetail的json字符串,注意是String
     * 微信单品优惠
     * 微信扫码支付 交易方式不支持
     * 支付宝智慧门店
     * 支付宝单品优惠
     */
    private String benefitdetail;

    /**
     * 渠道门店编号
     * 商户在支付渠道端的门店编号
     * 例如
     * 对于支付宝支付，支付宝门店编号
     * 对于微信支付，微信门店编号
     * 微信扫码支付 交易方式不支持
     */
    private String chnlstoreid;

    /**
     * 门店号
     * 通联系统门店号
     */
    private String subbranch;

    /**
     * 拓展参数
     * json字符串，注意是String
     * 一般用于渠道的活动参数填写
     */
    private String extendparams;

    /**
     * 终端ip
     * 用户下单和调起支付的终端ip地址
     * 云闪付JS支付时必填
     */
    private String cusip;

    /**
     * 支付完成跳转
     * 必须为https协议地址，且不允许带参数
     * 只支持云闪付JS支付，微信JS支付
     */
    private String front_url;

    /**
     * 证件号
     * 实名交易必填.填了此字段就会验证证件号和姓名
     * 暂只支持支付宝支付,微信支付(微信支付的刷卡支付除外)
     */
    private String idno;

    /**
     * 付款人真实姓名
     * 实名交易必填.填了此字段就会验证证件号和姓名
     * 暂只支持支付宝支付,微信支付(微信支付的刷卡支付除外)
     */
    private String truename;

    /**
     * 分账信息
     * 开通此业务需开通分账配置
     * 格式:
     * cusid:type:amount;cusid:type:amount…
     * 其中
     * cusid:接收分账的通联商户号
     * type分账类型（01：按金额  02：按比率）
     * 如果分账类型为02，则分账比率为0.5表示50%。如果分账类型为01，则分账金额以元为单位表示
     */
    private String asinfo;

    /**
     * 分期
     * 暂只支持支付宝花呗分期,支付宝信用卡分期
     * 仅支持 支付宝扫码支付 微信JS支付
     * 3  花呗分期3期
     * 6  花呗分期6期
     * 12  花呗分期12期
     * 3-cc 支付宝信用卡分期3期
     * 6-cc 支付宝信用卡分期6期
     * 12-cc 支付宝信用卡分期12期
     */
    private String fqnum;

    /**
     * 签名方式
     * RSA
     * SM2
     */
    private String signtype;

    /**
     * 银联pid
     * 仅支持代理商/服务商角色调用
     */
    private String unpid;

    /**
     * 签名
     */
    private String sign;

    /**
     * 终端信息
     * 终端信息的json字符串
     * paytype=A04,W04,U04时，terminfo字段必填
     */
    private String terminfo;

    /**
     * 收银员号
     */
    private String operatorid;

    /**
     * 原交易单号
     * 取消支付时使用
     */
    private String oldreqsn;

    /**
     * 原交易流水
     * 取消支付时使用
     */
    private String oldtrxid;

    private String trxid;

    public static class Builder {

        /**
         * 商户号
         * 实际交易的商户号
         */
        private String cusid;

        /**
         * 应用ID
         * 平台分配的APPID
         */
        private String appid;

        /**
         * 接口版本号
         * 默认填11
         */
        private String version;

        /**
         * 交易金额
         * 单位为分
         */
        private String trxamt;

        /**
         * 商户交易单号
         * 商户的交易订单号，保证商户平台唯一
         */
        private String reqsn;

        /**
         * 交易方式
         * W01 -- 微信扫码支付
         * W02 -- 微信JS支付
         * W06 -- 微信小程序支付
         * A01 -- 支付宝扫码支付
         * A02 -- 支付宝JS支付
         * A03 -- 支付宝APP支付
         * Q01 -- 手机QQ扫码支付
         * Q02 -- 手机QQ JS支付
         * U01 -- 银联扫码支付(CSB)
         * U02 -- 银联JS支付
         * S03 -- 数字货币H5
         */
        private String paytype;

        /**
         * 随机字符串
         * 商户自行生成的随机字符串
         */
        private String randomstr;

        /**
         * 订单标题
         * 订单商品名称，为空则以商户名作为商品名称
         * 最大100个字节(注：utf8下，一个中文字符是3个字节)
         */
        private String body;

        /**
         * 备注信息
         * 最大160个字节(80个中文字符)
         * 禁止出现+，空格，/，?，%，#，&，=这几类特殊符号
         */
        private String remark;

        /**
         * 有效时间
         * 订单有效时间，以分为单位，不填默认为5分钟
         * 最大1440分钟
         */
        private String validtime;

        /**
         * 支付平台用户标识
         * JS支付时使用
         * 微信支付-用户的微信openid
         * 付宝支付-用户user_id
         * 微信小程序-用户小程序的openid
         */
        private String acct;

        /**
         * 交易结果通知地址
         * 接收交易结果的通知回调地址，通知url必须为直接可访问的url，不能携带参数。
         * 若使用https,需使用默认443端口
         */
        private String notify_url;

        /**
         * 支付限制
         * no_credit--指定不能使用信用卡支付
         * 暂时只对微信支付和支付宝有效,仅支持no_credit
         */
        private String limit_pay;

        /**
         * 微信子appid
         * 微信小程序/微信公众号/APP的appid
         * 只对微信支付有效
         */
        private String sub_appid;

        /**
         * 订单优惠标识
         * 订单优惠标记，用于区分订单是否可以享受优惠，字段内容在微信后台配置券时进行设置，说明详见代金券或立减优惠
         * 只对微信支付有效
         * 微信扫码支付 交易方式不支持
         */
        private String goods_tag;

        /**
         * 优惠信息
         * Benefitdetail的json字符串,注意是String
         * 微信单品优惠
         * 微信扫码支付 交易方式不支持
         * 支付宝智慧门店
         * 支付宝单品优惠
         */
        private String benefitdetail;

        /**
         * 渠道门店编号
         * 商户在支付渠道端的门店编号
         * 例如
         * 对于支付宝支付，支付宝门店编号
         * 对于微信支付，微信门店编号
         * 微信扫码支付 交易方式不支持
         */
        private String chnlstoreid;

        /**
         * 门店号
         * 通联系统门店号
         */
        private String subbranch;

        /**
         * 拓展参数
         * json字符串，注意是String
         * 一般用于渠道的活动参数填写
         */
        private String extendparams;

        /**
         * 终端ip
         * 用户下单和调起支付的终端ip地址
         * 云闪付JS支付时必填
         */
        private String cusip;

        /**
         * 支付完成跳转
         * 必须为https协议地址，且不允许带参数
         * 只支持云闪付JS支付，微信JS支付
         */
        private String front_url;

        /**
         * 证件号
         * 实名交易必填.填了此字段就会验证证件号和姓名
         * 暂只支持支付宝支付,微信支付(微信支付的刷卡支付除外)
         */
        private String idno;

        /**
         * 付款人真实姓名
         * 实名交易必填.填了此字段就会验证证件号和姓名
         * 暂只支持支付宝支付,微信支付(微信支付的刷卡支付除外)
         */
        private String truename;

        /**
         * 分账信息
         * 开通此业务需开通分账配置
         * 格式:
         * cusid:type:amount;cusid:type:amount…
         * 其中
         * cusid:接收分账的通联商户号
         * type分账类型（01：按金额  02：按比率）
         * 如果分账类型为02，则分账比率为0.5表示50%。如果分账类型为01，则分账金额以元为单位表示
         */
        private String asinfo;

        /**
         * 分期
         * 暂只支持支付宝花呗分期,支付宝信用卡分期
         * 仅支持 支付宝扫码支付 微信JS支付
         * 3  花呗分期3期
         * 6  花呗分期6期
         * 12  花呗分期12期
         * 3-cc 支付宝信用卡分期3期
         * 6-cc 支付宝信用卡分期6期
         * 12-cc 支付宝信用卡分期12期
         */
        private String fqnum;

        /**
         * 签名方式
         * RSA
         * SM2
         */
        private String signtype;

        /**
         * 银联pid
         * 仅支持代理商/服务商角色调用
         */
        private String unpid;

        /**
         * 签名
         */
        private String sign;

        /**
         * 终端信息
         * 终端信息的json字符串
         * paytype=A04,W04,U04时，terminfo字段必填
         */
        private String terminfo;

        /**
         * 收银员号
         */
        private String operatorid;

        private String oldreqsn;

        private String oldtrxid;

        private String trxid;

        public Builder cusid(String cusid) {
            this.cusid = cusid;
            return this;
        }

        public Builder appid(String appid) {
            this.appid = appid;
            return this;
        }

        public Builder version(String version) {
            this.version = version;
            return this;
        }

        public Builder trxamt(String trxamt) {
            this.trxamt = trxamt;
            return this;
        }

        public Builder reqsn(String reqsn) {
            this.reqsn = reqsn;
            return this;
        }

        public Builder paytype(String paytype) {
            this.paytype = paytype;
            return this;
        }

        public Builder randomstr(String randomstr) {
            this.randomstr = randomstr;
            return this;
        }

        public Builder body(String body) {
            this.body = body;
            return this;
        }

        public Builder remark(String remark) {
            this.remark = remark;
            return this;
        }

        public Builder validtime(String validtime) {
            this.validtime = validtime;
            return this;
        }

        public Builder acct(String acct) {
            this.acct = acct;
            return this;
        }

        public Builder notify_url(String notify_url) {
            this.notify_url = notify_url;
            return this;
        }

        public Builder limit_pay(String limit_pay) {
            this.limit_pay = limit_pay;
            return this;
        }

        public Builder sub_appid(String sub_appid) {
            this.sub_appid = sub_appid;
            return this;
        }

        public Builder goods_tag(String goods_tag) {
            this.goods_tag = goods_tag;
            return this;
        }

        public Builder benefitdetail(String benefitdetail) {
            this.benefitdetail = benefitdetail;
            return this;
        }

        public Builder chnlstoreid(String chnlstoreid) {
            this.chnlstoreid = chnlstoreid;
            return this;
        }

        public Builder subbranch(String subbranch) {
            this.subbranch = subbranch;
            return this;
        }

        public Builder extendparams(String extendparams) {
            this.extendparams = extendparams;
            return this;
        }

        public Builder cusip(String cusip) {
            this.cusip = cusip;
            return this;
        }

        public Builder front_url(String front_url) {
            this.front_url = front_url;
            return this;
        }

        public Builder idno(String idno) {
            this.idno = idno;
            return this;
        }

        public Builder truename(String truename) {
            this.truename = truename;
            return this;
        }

        public Builder asinfo(String asinfo) {
            this.asinfo = asinfo;
            return this;
        }

        public Builder fqnum(String fqnum) {
            this.fqnum = fqnum;
            return this;
        }

        public Builder signtype(String signtype) {
            this.signtype = signtype;
            return this;
        }

        public Builder unpid(String unpid) {
            this.unpid = unpid;
            return this;
        }

        public Builder sign(String sign) {
            this.sign = sign;
            return this;
        }

        public Builder terminfo(String terminfo) {
            this.terminfo = terminfo;
            return this;
        }

        public Builder operatorid(String operatorid) {
            this.operatorid = operatorid;
            return this;
        }

        public Builder oldreqsn(String oldreqsn) {
            this.oldreqsn = oldreqsn;
            return this;
        }

        public Builder oldtrxid(String oldtrxid) {
            this.oldtrxid = oldtrxid;
            return this;
        }

        public Builder trxid(String trxid) {
            this.trxid = trxid;
            return this;
        }

        public AllInPaySybPayParam build() {
            return new AllInPaySybPayParam(this);
        }
    }
}
